#include    "aisinodb.h"
#include    "aisinoutils.h"
#include    <fstream>

SingleQA::SingleQA():QuestionAndAnswer(),answer("")
{
    this->setQuestionValue("");
}

SingleQA::~SingleQA()
{

}

bool SingleQA::isRightAnswer(const std::string& answer)
{
    return this->answer.compare(answer) == 0;
}

void SingleQA::setAnswerValue(const std::string& answer)
{
    this->answer = answer;
}


MultipleQA::MultipleQA():QuestionAndAnswer()
{
    this->setQuestionValue("");
    this->answers.clear();
}

MultipleQA::~MultipleQA()
{

}

bool MultipleQA::isRightAnswer(const std::string& answer)
{
    for(unsigned int i = 0 ;i < this->answers.size(); i++)
    {
        if(answers[i].compare(answer) == 0)
        {
            return true;
        }
    }
    return false;
}

void MultipleQA::setAnswerValue(const std::string& answer)
{
    this->answers.push_back(answer);
}



AisinoDB::AisinoDB()
{
    QA_List.clear();
}

AisinoDB::~AisinoDB()
{
    for(unsigned int i = 0 ; i < QA_List.size() ; i++)
    {
        delete QA_List[i];
    }
    QA_List.clear();
}

bool AisinoDB::isQuestionAnswer(const std::string& question,const std::string& answer)
{
    for(unsigned int i = 0; i < this->QA_List.size(); i++)
    {
        if( !QA_List[i]->isQuestionEqual(question) )
        {
            continue;
        }

        if( QA_List[i]->isRightAnswer(answer) )
        {
            return true;
        }
    }
    return false;

}

AisinoSingleDB::AisinoSingleDB():AisinoDB()
{

}

AisinoSingleDB::~AisinoSingleDB()
{

}

bool AisinoSingleDB::loadFile(const std::string& fileName)
{
    std::fstream singleDbFile(fileName,std::ios_base::in);
    if(!singleDbFile.is_open())
    {
        printf("can't open file: '%s'\n",fileName.c_str());
        return false;
    }

    std::string text;
    QuestionAndAnswer* questionAndAnswer = nullptr;
    unsigned int line = 0;
    bool questionTag = false;
    while(std::getline(singleDbFile,text))
    {
        line++;
        if(AisinoUtils::isStringWithTag(text,AISINO_QUESTION_TAG))
        {
            if(true == questionTag)
            {
                printf("single DB file format error, line:%d\n",line);
                break;
            }

            questionTag = true;

            questionAndAnswer = new SingleQA();
            std::string question = AisinoUtils::getStringBehindTag(text,AISINO_QUESTION_TAG);
            question = AisinoUtils::StringIgnoreSign(question);
            questionAndAnswer->setQuestionValue(question);
            QA_List.push_back(questionAndAnswer);

        }
        else if(AisinoUtils::isStringWithTag(text,AISINO_ANSWER_TAG))
        {
            if(false == questionTag)
            {
                printf("single DB file format error, line:%d\n",line);
                break;
            }

            questionTag = false;

            std::string answer = AisinoUtils::getStringBehindTag(text,AISINO_ANSWER_TAG);
            answer = AisinoUtils::StringIgnoreSign(answer);
            questionAndAnswer->setAnswerValue(answer);
        }
        else
        {
            printf("single DB file format error, line:%d\n",line);
            break;
        }
    }

    singleDbFile.close();

    return true;
}

AisinoMultipleDB::AisinoMultipleDB():AisinoDB()
{

}

AisinoMultipleDB::~AisinoMultipleDB()
{

}

bool AisinoMultipleDB::loadFile(const std::string& fileName)
{
    std::fstream multipleDbFile(fileName,std::ios_base::in);
    if(!multipleDbFile.is_open())
    {
        printf("can't open file: '%s'\n",fileName.c_str());
        return false;
    }

    std::string text;
    QuestionAndAnswer* questionAndAnswer = nullptr;
    unsigned int line = 0;
    bool questionTag = false;
    while(std::getline(multipleDbFile,text))
    {
        line++;
        if(AisinoUtils::isStringWithTag(text,AISINO_QUESTION_TAG))
        {
            if(true == questionTag)
            {
                printf("multiple DB file format error, line:%d\n",line);
                break;
            }

            questionTag = true;

            questionAndAnswer = new MultipleQA();
            std::string question = AisinoUtils::getStringBehindTag(text,AISINO_QUESTION_TAG);
            question = AisinoUtils::StringIgnoreSign(question);
            questionAndAnswer->setQuestionValue(question);
            QA_List.push_back(questionAndAnswer);

        }
        else if(AisinoUtils::isStringWithTag(text,AISINO_ANSWER_TAG))
        {
            questionTag = false;
            std::string answer = AisinoUtils::getStringBehindTag(text,AISINO_ANSWER_TAG);
            answer = AisinoUtils::StringIgnoreSign(answer);
            questionAndAnswer->setAnswerValue(answer);
        }
        else
        {
            printf("multiple DB file error, line:%d\n",line);
            break;
        }
    }

    multipleDbFile.close();

    return true;
}


